import { Trans } from "../component/Trans";
import { TransInstance } from "../component/TransInstance";
import { any } from "../core/logic";
import { Euler } from "../core/math/Euler";
import { Matrix4 } from "../core/math/Matrix4";
import { Quaternion } from "../core/math/Quaternion";
import { Vector3 } from "../core/math/Vector3";
import { Entity } from "./Entity";
/**
 * 一个特殊的Entity.默认就带有Trans组件。
 * @class
 * @extends w.Entity
 * @memberof w
 * @extends {w.Entity}
 */
class Object3D extends Entity {
    /**
     * Object3D对象构造函数。
     * @constructor
     * @param {*} opts
     * @see w.Entity#setVisibility
     * @param {w.component.Tran} opts.trans 【可选,缺省:undefine】如果设置trans,则优先trans;position scale rotation的设置忽略。
     * @param {Number} opts.maxInstanceNum  Object3D对象的实例化个数，缺省:1,非实例化绘制。当超过最大值时，系统自动扩容最大值*2,建议大小给10
     * @param {Array} opts.position 【可选,缺省:[0,0,0]】位置信息。
     * @param {Array} opts.sclae 【可选,缺省:[1,1,1]】缩放信息。
     * @param {Array} opts.rotation 【可选,缺省:[0,0,0]】旋转信息。
     * @example
     * //非实例化
     * //方式1
     * let object=new Object({position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],maxInstanceNum:1});
     * //方式2
     * let trans=new w.component.Trans({position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],maxInstanceNum:1})
     * let object=new Object({trans});
     * //实例化
     * //方式1
     * let object=new Object({position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],maxInstanceNum:10000});
     * //方式2
     * let trans=new w.component.TransInstance({position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],maxInstanceNum:1})
     * let object=new Object({trans});
     */
    constructor(opts = {}) {
        super(opts);
        this._type = "Object3D";
        if (opts.trans) {
            this.addComponent(opts.trans);
        } else {
            //判断是实例化绘制还是非实例化绘制。
            opts.maxInstanceNum = any(opts.maxInstanceNum, 1);
            if (opts.maxInstanceNum === 1) {
                this.addComponent(new Trans(opts));
            } else {
                this.addComponent(new TransInstance(opts));
            }
        }

    }
    /**
     * 
     * @param {object} trans 
     * {
     *  position:
     *  scale:
     *  rotation:
     * }
     */
    addInstance(trans, first = false) {
        if (this.trans.hash == "transinstance") {
            if (first) {//第一次添加修改trans值
                if (trans.position) {
                    this.trans.getInstance(0).position = trans.position
                }
                if (trans.sclae) {
                    this.trans.getInstance(0).sclae = trans.sclae
                }
                if (trans.rotation) {
                    this.trans.getInstance(0).rotation = trans.rotation
                }

            } else {
                this.trans.add(new Trans(trans));
            }
        } else {
            //寻找所有的multiTrans
            let entities = this.getAllInstance();
            for (let i = 0; i < entities.length; i++) {
                let mt = entities[i].trans;
                const curTrans = mt.getInstance(0);
                let matrix = new Matrix4();
                let position = new Vector3(0, 0, 0);
                let quat = new Quaternion();
                let scale = new Vector3(1, 1, 1);

                if (trans.position) {
                    position.fromArray(trans.position);
                }
                if (trans.scale) {
                    scale.fromArray(trans.scale);
                }
                if (trans.rotation) {
                    let euler = new Euler(trans.rotation[0], trans.rotation[1], trans.rotation[2]);
                    quat.setFromEuler(euler);
                    euler = null;
                }
                matrix.compose(position, quat, scale);
                if (first) {//第一次添加修改trans值
                    curTrans.preApplyMatrix4(matrix);
                } else {
                    let t = new Trans();
                    t.applyMatrix4(mt.base);
                    t.preApplyMatrix4(matrix);
                    mt.add(t);
                }

            }
        }
    }
    removeInstance(index) {
        if (this.trans.maxInstanceNum > 1) {
            this.trans.remove(this.trans._transArr[index].id);
        } else {

        }
    }

}
export { Object3D }